"""
FileName：request_utils.py
Description：
Author：gaojiahui
Time：2025/8/13 20:42
Website：https://gitee.com/gao-jiahui
"""
import json
import logging
from time import sleep

import requests
from requests import RequestException

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger("HttpClient")

class HttpRequest:
    """封装HTTP请求的工具类"""

    def __init__(self,base_url="",timeout=10,max_retries=3,retry_delay=1):
        self.base_url = base_url
        self.session = requests.Session()
        self.timeout = timeout
        self.max_retries = max_retries
        self.retry_delay = retry_delay
        self.headers = {
            "Content-Type":"application/json",
            "User-Agent":"Pytest-Automation/1.0"
        }

    def add_header(self,key,value):
        """添加自定义请求头"""
        self.headers[key] = value

    def request(self,method,endpoint,**kwargs):
        """发送HTTP请求"""
        url = f"{self.base_url}{endpoint}"

        # 合并请求头
        headers = {**self.headers,**kwargs.pop("headers",{})}

        # 重试机制
        for attempt in range(self.max_retries):
            try:
                # 记录请求日志
                self._log_request(method,url, kwargs)

                # 发送请求
                response = self.session.request(method=method,
                                                url=url,
                                                headers=headers,
                                                timeout=self.timeout,
                                                **kwargs
                                                )
                # 记录响应日志
                self._log_response(response)

                # 处理响应
                return self._handle_response(response)

            except RequestException as e:
                if attempt < self.max_retries - 1:
                    logger.warning(f"请求失败 ({e}),第{attempt + 1}次重试...")
                    sleep(self.retry_delay)
                    continue
                else:
                    logger.error(f"请求失败({e}),达到最大重试次数")
                    raise

    def get(self,endpoint,**kwargs):
        """发送GET请求"""
        return self.request("GET",endpoint,**kwargs)

    def post(self,endpoint,data=None,json=None,**kwargs):
        """发送POST请求"""
        return self.request("POST",endpoint,data=data,json=json,**kwargs)

    @staticmethod
    def _log_request(method, url, kwargs):
        """记录请求日志"""
        log_data = {
            "method":method,
            "url":url,
            "params":kwargs.get("params"),
            "data":kwargs.get("data"),
            "json":kwargs.get("json")
        }
        logger.info(f"发送请求:{json.dumps(log_data,indent=2,ensure_ascii=False)}")

    @staticmethod
    def _log_response(response):
        """记录响应日志"""
        try:
            response_data = response.json()
        except json.JSONDecodeError:
            response_data = response.text[:200] + "..." if len(response.text) > 200 else response.text

        log_data = {
            "status":response.status_code,
            "url":response.url,
            "headers":dict(response.headers),
            "data":response_data
        }
        logger.info(f"收到响应:{json.dumps(log_data,indent=2,ensure_ascii=False)}")
    @staticmethod
    def _handle_response(response):
        """处理响应并转换为 JSON"""
        try:
            response.raise_for_status()
            return response.json()
        except json.JSONDecodeError:
            return {"status_code":response.status_code,"text":response.text}
        except requests.HTTPError as e:
            error_msg = f"HTTP错误:{e}"
            logger.error(error_msg)
            try:
                return {"error":error_msg,"details":response.json()}
            except json.JSONDecodeError:
                return {"error":error_msg,"details":response.text}